package com.seven.smartsnmp.impl;

import com.seven.smartsnmp.base.DefaultConstant;
import com.seven.smartsnmp.base.MyException;
import com.seven.smartsnmp.base.SysResource;
import com.seven.smartsnmp.handler.HandlerFactory;
import com.seven.smartsnmp.snmp.SNMPAPI;
import com.seven.smartsnmp.snmp.SNMPComunication;
import com.seven.smartsnmp.snmp.SNMPTarget;
import net.percederberg.mibble.MibValueSymbol;
import net.percederberg.mibble.value.ObjectIdentifierValue;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.smi.Variable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class SNMPAPIImpl implements SNMPAPI {
    private static final Logger log = LoggerFactory.getLogger(SNMPAPIImpl.class);
    //snmpAPi接口
    private volatile static SNMPAPIImpl snmpapi;

    /**
     * 加载mib文件
     *
     * @param mibFile
     * @throws MyException
     */

    /***
     * 根据oid 获取MibValueSymbol
     * @param oid
     * @return
     * @throws MyException
     */

    @Override
    public MibValueSymbol getMibSymbolByOid(String oid) throws MyException {
        if (oid.startsWith(".")) {
            oid = oid.replaceFirst(".", "");
        }
        ObjectIdentifierValue iso = SysResource.getMibload().getRootOid();
        ObjectIdentifierValue match = iso.get(oid);
        if (match == null) {
            log.info("oid:" + oid + "未找到该oid的节点");
            return null;
        } else {
            return match.getSymbol();
        }
    }


    /**
     * 根据mib获取对象
     *
     * @param obj
     * @param snmpTarget
     * @return
     * @throws MyException
     */
    @Override
    public Object getMibObject(Object obj, SNMPTarget snmpTarget) throws MyException, IOException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            HandlerFactory.getRefreshHandler().reFresh(obj, snmp, target);
        } catch (Exception e) {
            throw new MyException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
        return obj;

    }

    /**
     * 设置值到mib中根据oid
     *
     * @param oid
     * @param nodeOid
     * @param value
     * @param snmpTarget
     * @throws MyException
     */
    @Override
    public void setOIDValue(String oid, String nodeOid, String value, SNMPTarget snmpTarget) throws MyException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            HandlerFactory.getSetHandler().setValue(oid, nodeOid, value, snmp, target);
        } catch (Exception e) {
            throw new MyException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    @Override
    public String getOIDValue(String oid, SNMPTarget snmpTarget) throws MyException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable variable = HandlerFactory.getSelectHandler().getValue(oid, snmp, target);
            if (variable == null) {
                return null;
            } else {
                return variable.toString();
            }
        } catch (Exception e) {
            log.
            throw new MyException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    @Override
    public Long getOIDLongValue(String oid, SNMPTarget snmpTarget) throws MyException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable variable = HandlerFactory.getSelectHandler().getValue(oid, snmp, target);
            if (variable == null) {
                return null;
            } else {
                return variable.toLong();
            }
        } catch (Exception e) {
            throw new MyException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }

    }

    /**
     * 校验是否在线
     *
     * @param snmpTarget
     * @throws MyException
     */
    @Override
    public boolean checkSnmpAgentActive(SNMPTarget snmpTarget) throws MyException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            String str = HandlerFactory.getSelectHandler().getValue("1.3.6.1.2.1.1.1.0", snmp, target).toString();
            if (StringUtils.isNotBlank(str)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception exception) {
            return false;
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }


    }

    /**
     * 获取下一个节点数据
     *
     * @param oid
     * @param snmpTarget
     * @return
     * @throws MyException
     */
    @Override
    public String getNextOIDValue(String oid, SNMPTarget snmpTarget) throws MyException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable value = HandlerFactory.getSelectHandler().getNextValue(oid, snmp, target);
            return value == null ? null : value.toString();
        } catch (Exception e) {
            throw new MyException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    /**
     * 更新值
     *
     * @param object
     * @param snmpTarget
     * @throws MyException
     */
    @Override
    public void update(Object object, SNMPTarget snmpTarget) throws MyException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            HandlerFactory.getUpdateHandler().update(object, snmp, target);
        } catch (Exception e) {
            throw new MyException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }


    }

    /**
     * 获取表格数据
     *
     * @param clazz
     * @param snmpTarget
     * @return
     * @throws MyException
     */
    @Override
    public List getAllTableData(Class clazz, SNMPTarget snmpTarget) throws MyException {
        Snmp snmp = null;
        List retList = new ArrayList();
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            retList = HandlerFactory.getSelectHandler().getAllTableData(snmp, target, clazz);
            return retList;
        } catch (Exception e) {
            throw new MyException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    /**
     * 获取全部表数据
     *
     * @param snmpTarget
     * @param tableOIDs
     * @return
     * @throws MyException
     */
    @Override
    public List<List<String>> getAllOIDTableData(SNMPTarget snmpTarget, List<String> tableOIDs) throws MyException, IOException {
        Snmp snmp = SNMPComunication.createSnmp(snmpTarget);
        List<List<String>> resList = new ArrayList<>();
        try {
            Target Target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            List list = HandlerFactory.getSelectHandler().getAllOIDTableData(snmp, Target, tableOIDs);
            resList = list;
            return resList;
        } catch (Exception e) {
            throw new MyException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    @Override
    public void addTableRow(Object object, SNMPTarget snmpTarget) throws MyException, IOException {
        Snmp snmp = SNMPComunication.createSnmp(snmpTarget);
        try {
            Target Target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            HandlerFactory.getAddHandler().addTable(object, snmp, Target);
        } catch (Exception e) {
            throw new MyException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    @Override
    public void delTableRow(Object object, SNMPTarget snmpTarget) throws MyException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target Target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            HandlerFactory.getDelHandler().delTable(object, snmp, Target);
        } catch (Exception e) {
            throw new MyException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }


}
